package com.example.ploy4j.controller;

import com.example.ploy4j.dto.ServerConfigDto;
import com.example.ploy4j.service.ServerConfigService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/api/server-configs")
@RequiredArgsConstructor
public class ServerConfigController {

    private static final Logger logger = LoggerFactory.getLogger(ServerConfigController.class);
    private final ServerConfigService serverConfigService;
    private final Validator validator; // Spring's Validator for programmatic validation if needed

    @PostMapping
    @ResponseBody
    public ResponseEntity<?> createServerConfig(@Valid @RequestBody ServerConfigDto serverConfigDto) {
        ServerConfigDto createdConfig = serverConfigService.createServerConfig(serverConfigDto);
        return new ResponseEntity<>(createdConfig, HttpStatus.CREATED);
    }

    @GetMapping
    @ResponseBody
    public ResponseEntity<List<ServerConfigDto>> getAllServerConfigsApi() {
        List<ServerConfigDto> configs = serverConfigService.getAllServerConfigs();
        return ResponseEntity.ok(configs);
    }

    @GetMapping("/{id}")
    @ResponseBody
    public ResponseEntity<ServerConfigDto> getServerConfigById(@PathVariable Long id) {
        return serverConfigService.getServerConfigById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/by-name/{name}")
    @ResponseBody
    public ResponseEntity<ServerConfigDto> getServerConfigByName(@PathVariable String name) {
        return serverConfigService.getServerConfigByName(name)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @PutMapping("/{id}")
    @ResponseBody
    public ResponseEntity<?> updateServerConfig(@PathVariable Long id, @Valid @RequestBody ServerConfigDto serverConfigDto) {
        try {
            ServerConfigDto updatedConfig = serverConfigService.updateServerConfig(id, serverConfigDto);
            return ResponseEntity.ok(updatedConfig);
        } catch (jakarta.persistence.EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    public ResponseEntity<Void> deleteServerConfig(@PathVariable Long id) {
        try {
            serverConfigService.deleteServerConfig(id);
            return ResponseEntity.noContent().build();
        } catch (jakarta.persistence.EntityNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @GetMapping("/manage")
    public String manageServerConfigsPage(Model model) {
        // This endpoint serves the HTML page which is now loaded as a fragment by index.html
        // No changes needed here for SPA content loading itself,
        // but the served HTML (manage-servers.html) has been overhauled.
        // model.addAttribute("serverConfigs", serverConfigService.getAllServerConfigs()); // Data is fetched by JS now
        // model.addAttribute("newServerConfig", new ServerConfigDto()); // Modal is JS driven
        return "configs/manage-servers";
    }

    @PostMapping("/{id}/test-connection")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> testServerConnection(@PathVariable Long id) {
        try {
            return ResponseEntity.ok(serverConfigService.testConnection(id));
        } catch (jakarta.persistence.EntityNotFoundException e) {
            logger.warn("Test connection failed for ID {}: {}", id, e.getMessage());
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body(Map.of("success", false, "message", "服务器配置未找到: " + id));
        } catch (Exception e) {
            logger.error("Error testing connection for ID {}:", id, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("success", false, "message", "测试连接时发生内部错误: " + e.getMessage()));
        }
    }

    @PostMapping("/test-unsaved-connection")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> testUnsavedConnection(@RequestBody ServerConfigDto serverConfigDto) {
        // Programmatic validation for fields required for connection test, if not covered by @Valid on DTO for this specific use case
        // For simplicity, service layer does basic null/empty checks for now.
        // You could use a specific DTO for this endpoint with only necessary fields and @Valid.
        try {
            Map<String, Object> result = serverConfigService.testUnsavedConnection(serverConfigDto);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            logger.error("Error testing unsaved connection: {}", serverConfigDto, e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("success", false, "message", "测试连接时发生内部错误: " + e.getMessage()));
        }
    }
} 